﻿// See https://aka.ms/new-console-template for more information
using Device;
using Microsoft.Extensions.Logging;
using ModbusPlugin;
using PLC.ModBusMaster;
using PluginInterface;
using System.Text;

Console.WriteLine("Hello, World!");
using ILoggerFactory factory = LoggerFactory.Create(builder => builder.AddConsole());
ILogger logger = factory.CreateLogger(typeof(DeviceModBusMaster));
var deviceModBusMaster = new DeviceModBusMaster("m1",logger);
deviceModBusMaster.MinPeriod = 1000;
deviceModBusMaster.IpAddress = "127.0.0.1";
deviceModBusMaster.SlaveAddress = 1;
deviceModBusMaster.Port = 502;
deviceModBusMaster.Connect();

ILogger loggerDeivce = factory.CreateLogger<DeviceService>();
var device = new DeviceInfo
{
    AutoStart = true,
    DeviceName = "我的Modbus",
    DriverId = Guid.NewGuid(),
    DeviceConfigs = new List<DeviceConfig>
    {
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="端口号",DeviceConfigName="Port",Value="502" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="主站类型",DeviceConfigName="MasterType",Value="Tcp",EnumInfo="{\"Tcp\":0,\"Udp\":1,\"Rtu\":2,\"RtuOnTcp\":3,\"RtuOnUdp\":4,\"Ascii\":5,\"AsciiOnTcp\":6,\"AsciiOnUdp\":7}" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="最小通讯周期ms",DeviceConfigName="MinPeriod",Value="0" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="超时时间ms",DeviceConfigName="Timeout",Value="3000" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="串口名",DeviceConfigName="PortName",Value="COM1" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="停止位",DeviceConfigName="StopBits",Value="One" ,EnumInfo="{\"None\":0,\"One\":1,\"Two\":2,\"OnePointFive\":3}" },
        //new DeviceConfig{ DataSide=DataSide.AnySide,Description="从站号",DeviceConfigName="SlaveAddress",Value="1" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="设备Id",DeviceConfigName="DeviceId" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="波特率",DeviceConfigName="BaudRate",Value="9600" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="数据位",DeviceConfigName="DataBits",Value="8" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="校验位",DeviceConfigName="Parity",Value="None",EnumInfo="{\"None\":0,\"Odd\":1,\"Even\":2,\"Mark\":3,\"Space\":4}" },
        new DeviceConfig{ DataSide=DataSide.AnySide,Description="IP地址",DeviceConfigName="IpAddress",Value="127.0.0.1" },
    },
    DeviceVariables = new List<DeviceVariable>
    {
        //new DeviceVariable{ Name="1号参数",Method="HoldingRegisters",DeviceAddress="0",DataType=DataTypeEnum.Int16,Index=0},
        //new DeviceVariable{ Name="4号参数",Method="HoldingRegisters",DeviceAddress="4",DataType=DataTypeEnum.Float,Index=1},
        //new DeviceVariable{ Name="3号参数",Method="HoldingRegisters",DeviceAddress="3",DataType=DataTypeEnum.Int16,Index=2},
        //new DeviceVariable{ Name="2号参数",Method="HoldingRegisters",DeviceAddress="1",DataType=DataTypeEnum.Int16,Index=4}
        // new DeviceVariable{ Name="1号参数",Method="ReadMultiple",DeviceAddress="1|3,0,4,m1",DataType=DataTypeEnum.Int16,Index=0},
        //new DeviceVariable{ Name="4号参数",Method="HoldingRegisters",DeviceAddress="4",DataType=DataTypeEnum.Float,Index=1}
    }
};
//var multipleAddress = new DeviceVariable
//{
//    Name = $"6125号参数",
//    Method = "ReadMultiple",
//    DataType = DataTypeEnum.Int16,
//};
//device.DeviceVariables.Add(multipleAddress);
//StringBuilder sbAddress = new StringBuilder();
//sbAddress.Append("1|");//slaveId，可以不填
////sbAddress.Append("3,6,125,m2");//功能,起始地址,长度,缓存名称
//sbAddress.Append("3,0,1,m2");//功能,起始地址,长度,缓存名称
//multipleAddress.DeviceAddress = sbAddress.ToString();

var multipleAddress0 = new DeviceVariable
{
    Name = $"6125号参数",
    Method = "HoldingRegisters",
    DataType = DataTypeEnum.Int16,
    EndianType = EndianEnum.None,
    DeviceAddress = "0"
};
device.DeviceVariables.Add(multipleAddress0);
var multipleAddress2 = new DeviceVariable
{
    Name = $"6125号参数",
    Method = "HoldingRegisters",
    DataType = DataTypeEnum.Float,
    EndianType = EndianEnum.None,
    DeviceAddress = "1"
};
device.DeviceVariables.Add(multipleAddress2);
StringBuilder sbAddress2 = new StringBuilder();
sbAddress2.Append("1|");//slaveId，可以不填
//sbAddress.Append("3,6,125,m2");//功能,起始地址,长度,缓存名称
sbAddress2.Append("3,1,1,m2");//功能,起始地址,长度,缓存名称
//multipleAddress2.DeviceAddress = sbAddress2.ToString();

//var multipleAddress3 = new DeviceVariable
//{
//    Name = $"6125号参数",
//    Method = "ReadMultipleV2",
//    DataType = DataTypeEnum.Float,
//    EndianType = EndianEnum.None,
//    DeviceAddress = "3,1,1,m2"
//};
//device.DeviceVariables.Add(multipleAddress3);

using var deivceService = new DeviceService(deviceModBusMaster, loggerDeivce, device);
//deivceService.StartCollection();

var paramVariables = new List<DeviceVariable> { };
for (var i = 3; i < 1000; i++)
{
    var multipleAddress1 = new DeviceVariable
    {
        Name = $"{i}号参数",
        Method = "HoldingRegisters",
        DataType = DataTypeEnum.Int16,
        DeviceAddress = i.ToString()
    };
    device.DeviceVariables.Add(multipleAddress1);
}
//var readMuls = paramVariables.GroupBy(t => new
//{
//    t.Method,
//    t.DataType
//}).Select(t => new
//{
//    t.Key.Method,
//    t.Key.DataType,
//    StartAddress = t.Min(m => m.DeviceAddress),
//    EndAddress = t.Max(m => m.DeviceAddress)
//}).ToList();
//var pageSize = 125;
//foreach (var readMul in readMuls)
//{
//    var startAddress = int.Parse(readMul.StartAddress);
//    var endAddress = int.Parse(readMul.EndAddress);
//    var count = endAddress - startAddress;
//    var pageCount = count / pageSize;
//    for (var i = 0; i <= pageCount; i++)
//    {
//        var length = 125;
//        var _startAddress = startAddress + i * pageSize;
//        if (_startAddress + 125 > endAddress)
//        {
//            length = endAddress - _startAddress + 1;
//        }
//        else
//        {
//            length = 125;
//        }
//        if (readMul.Method == "HoldingRegisters")
//        {
//            var key = $"m_{_startAddress}_{i}";
//            var multipleAddress1 = new DeviceVariable
//            {
//                Name = $"3,{readMul.StartAddress},{key}号参数",
//                Method = "ReadMultiple",
//                DataType = DataTypeEnum.Int16,
//                DeviceAddress = $"3,{_startAddress},{length},{key}"
//            };
//            device.DeviceVariables.Add(multipleAddress1);
//        }
//    }
//}


//using var deivceService = new DeviceService(deviceModBusMaster, loggerDeivce, device);


ILogger loggerWriter = factory.CreateLogger(typeof(DeviceModBusMaster));
var deviceModBusMasterWriter = new DeviceModBusMaster("m2", loggerWriter);
deviceModBusMasterWriter.MinPeriod = 1000;
deviceModBusMasterWriter.IpAddress = "127.0.0.1";
deviceModBusMasterWriter.Port = 502;
deviceModBusMasterWriter.Connect();

Task.Run(async () =>
{
    var index = 0;
    while (true)
    {
        await Task.Delay(1000);

        var r = await deviceModBusMasterWriter.WriteAsync("", "HoldingRegisters", new DriverAddressIoArgModel
        {
            Address = "1|0",
            Value = index++,
            ValueType = DataTypeEnum.Int16,
            EndianType = EndianEnum.None
        });

        var rf = await deviceModBusMasterWriter.WriteAsync("", "HoldingRegisters", new DriverAddressIoArgModel
        {
            Address = "1|6",
            Value = index / 2.0,
            ValueType = DataTypeEnum.Float,
            EndianType = EndianEnum.None
        });
        var r1 = await deviceModBusMasterWriter.WriteAsync("", "Coil", new DriverAddressIoArgModel
        {
            Address = "4|0",
            Value = 1,
            ValueType = DataTypeEnum.Bool,
            EndianType = EndianEnum.None
        });

        var ret = await deviceModBusMasterWriter.WriteAsync("", "Coil", new DriverAddressIoArgModel
        {
            Address = "4|1",
            Value = index % 2,
            ValueType = DataTypeEnum.Bool,
            EndianType = EndianEnum.None
        });
    }
});

Console.ReadKey();